import {handleLifecycle, initT} from "@/lifecycle";
import {
  $el,
  $root,
  $data,
  $props,
  $parent,
  _vNode,
  $children,
  _uid,
  $refs,
  $options,
  _isMounted,
  _isDestroyed,
  _isBeingDestroyed,
  SybComponentName,
  AppComponent,
  $nextTick,
} from "@/instance";
import {isObject} from "@/utils";
import reactive from "@/reactive";

let uid = 0;

const initOptions = (vm, options) => {
  vm[_uid] = ++uid;
  vm[$el] = null;
  vm[$data] = null;
  vm[$props] = null;
  vm[$parent] = null;
  vm[_vNode] = null;
  vm._flag = 'coder_why';
  // vm[$nextTick] = Promise.resolve().then;
  vm[$nextTick] = reactive._nextTick;
  vm[SybComponentName] = vm[_uid] === 1 ? AppComponent : null;
  if (!options) return;
  if (!isObject(options)) throw new Error('options should be an object.')
  vm[$options] = options || {};
}

const initLifecycle = (vm) => {
  const parent = vm[$options].parent;
  vm[$parent] = parent;
  vm[$root] = parent ? parent[$root] : vm

  vm[$children] = []
  vm[$refs] = {}
  vm[_isMounted] = false
  vm[_isDestroyed] = false
  vm[_isBeingDestroyed] = false;

  handleLifecycle(vm, initT)
}

class Vue {
  constructor(options) {
    const context = this;
    initOptions(context, options);
    initLifecycle(context);
  }

  static extend(options) {
    class Super extends this {
      constructor() {
        super(options);
      }
    }

    return Super;
  }
}

window.Vue = Vue;

